package com.it.gmall.activity.listener;

import com.it.gmall.activity.redis.CacheHelper;
import com.it.gmall.activity.service.ActivityService;
import com.it.gmall.common.constant.RedisConst;
import com.it.gmall.model.activity.SeckillGoods;
import com.it.gmall.model.activity.UserRecode;
import com.it.gmall.mq.consts.MqConst;
import com.rabbitmq.client.Channel;
import jodd.util.ObjectUtil;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;


@Component
public class ActivityListener {
    @Autowired
    private ActivityService activityService;
    @Autowired
    private RedisTemplate redisTemplate;

    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_TASK),
            value = @Queue(value = MqConst.QUEUE_TASK_1,durable = "true",autoDelete = "false"),
            key = {MqConst.ROUTING_TASK_1}
        )
    )
    public void addGoodsListener(Message message, Channel channel){
        try {
            // 定时添加商品
            activityService.activityAddSeckillGoods();
            // 手动应答消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_SECKILL_USER),
            value = @Queue(value = MqConst.QUEUE_SECKILL_USER,durable = "true",autoDelete = "false"),
            key = {MqConst.ROUTING_SECKILL_USER}
    )
    )
    public void seckillOrder(UserRecode userRecode, Message message, Channel channel){
        try {
            // 1.校验状态位 是否有库存
            Object o1 = CacheHelper.get(userRecode.getSkuId().toString());
            if("1".equals(o1)){ // 0: 有库存 1:没有库存
                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
                return;
            }

            // 2.校验用户是否已经下单过 seckill:orders:users:
            Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(RedisConst.SECKILL_ORDERS_USERS + userRecode.getUserId() + ":" + userRecode.getSkuId(), "");
            if(!aBoolean){ // 用户已经下单过
                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
                return;
            }

            // 3.获取库存商品 seckill:stock:
            Object o = redisTemplate.opsForList().rightPop(RedisConst.SECKILL_STOCK_PREFIX + userRecode.getSkuId());
            if(StringUtils.isEmpty(o)){ // 没有商品了 秒杀失败 抢购失败
                // 更新状态位 0:有货 1:无货
                redisTemplate.convertAndSend("seckillpush",userRecode.getSkuId()+":1");
                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
                return;
            }

            // 4.抢购成功
            // 4.1 查询这个商品
            SeckillGoods item = activityService.item(userRecode.getSkuId());
            // 4.2 记录用户抢购到了这个商品 seckill:orders:userId:skuId
            redisTemplate.opsForValue().set(RedisConst.SECKILL_ORDERS+userRecode.getUserId() + ":" + userRecode.getSkuId(),item);
            // todo 后续操作 同步DB 删除redis中没有货的商品 。。。
            // 手动应答消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
